package com.franklin.java.action.sql.entity.ui;

import com.flychord.jdk.util.tuple.Tuple3;
import com.franklin.java.entity.sql.ColumnInfo;
import com.franklin.java.entity.sql.MappingType;
import com.franklin.java.utils.PsiUtils;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.franklin.plugins.common.utils.StringHelper;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiClass;
import com.intellij.ui.treeStructure.SimpleNode;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.flychord.jdk.util.tuple.TupleAble.tuple;
import static com.franklin.java.action.sql.entity.ui.GenerateEntityClassForm.prefixTab;

/**
 * @author Franklin
 * @since 2021/9/13 15:37
 */
public class DiscriminatorNode extends ResultMapChildNode{

    private String javaType;
    private String column;

    protected DiscriminatorNode(SimpleNode aParent, String javaType, String column) {
        super(aParent);
        this.javaType = javaType;
        this.column = column;
        setProperties();
    }

    @Override
    protected void setProperties() {
        this.properties = Lists.newArrayList(
            tuple("javaType",javaType),
            tuple("column",column)
        );
    }


    @Override
    public boolean isSingleTag() {
        return false;
    }

    @Override
    public Tuple3<String, String, String> getJavaField(
        Map<String, List<ColumnInfo>> columnNameColumnsMap,
        Map<String,String> tableNameTableCommentMap,
        Set<String> importSet
    ) {
        List<ResultMapChildNode> childrenNodeList = this.getChildrenNodeList();
        String typeQualifiedName = childrenNodeList.stream()
            .filter(childNode -> childNode instanceof CaseNode)
            .map(childNode -> (CaseNode) childNode)
            .map(caseNode -> caseNode.getProperty("resultType"))
            .filter(resultType -> DataCheckUtils.isNotEmpty(resultType) && !resultType.equals("resultType"))
            .map(resultType -> PsiUtils.findClassByQualifiedOrSimpleName(project, project.getBasePath(), resultType))
            .filter(Objects::nonNull)
            .findFirst()
            .map(PsiClass::getQualifiedName)
            .orElse(getDefaultJavaType());
        importSet.add(typeQualifiedName);

        String type = StringHelper.getSimpleName(typeQualifiedName);
        String column = this.getProperty("column");
        String field = StringHelper.underlineToCamel(column);

        StringBuilder fieldBuilder = new StringBuilder();
        fieldBuilder
            .append(prefixTab).append("private ").append(type).append(' ').append(field).append(';').append('\n');

        return tuple(fieldBuilder.toString(),field,type);
    }

    @Override
    public List<String> getChildNodeNames() {
        return Lists.newArrayList("case");
    }

    public static class CaseNode extends ResultMapChildNode{

        private String value;
        private String resultType;
        private String resultMap;

        protected CaseNode(SimpleNode aParent, String value, String resultType, String resultMap) {
            super(aParent);
            this.value = value;
            this.resultType = resultType;
            this.resultMap = resultMap;
            setProperties();
        }

        @Override
        protected void setProperties() {
            this.properties = Lists.newArrayList(
                tuple("value",value),
                tuple("resultType",resultType),
                tuple("resultMap",resultMap)
            );
        }

        @Override
        public boolean isSingleTag() {
            return false;
        }
    }
}
